package com.cong.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cong.project.common.ErrorCode;
import com.cong.project.exception.BusinessException;
import com.cong.project.mapper.ContentMapper;
import com.cong.project.model.entity.*;
import com.cong.project.model.enums.CollectStatusEnum;
import com.cong.project.model.enums.ContentTypeEnum;
import com.cong.project.model.enums.LikeStatusEnum;
import com.cong.project.model.request.*;
import com.cong.project.model.vo.PostDetailVo;
import com.cong.project.model.vo.PostVo;
import com.cong.project.service.*;
import com.cong.project.utils.ThreadPoolUtils;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * @author 86188
 * @description 针对表【content(用户发布内容信息表)】的数据库操作Service实现
 * @createDate 2022-10-11 15:34:33
 */
@Service
public class ContentServiceImpl extends MPJBaseServiceImpl<ContentMapper, Content> implements ContentService {
    @Resource
    private ContentImagesService contentImagesService;
    @Resource
    private LikeNumService likeNumService;
    @Resource
    private LikeService likeService;
    @Resource
    private CollectService collectService;
    @Resource
    private CollectNumService collectNumService;

    @Override
    public IPage<PostVo> getPostList(TokenUserRequest tokenUserRequest, PostQueryRequest pageRequest) {
        Long userId = tokenUserRequest.getId();
        Long type = pageRequest.getType();

        MPJLambdaWrapper<PostVo> wrapper = new MPJLambdaWrapper<PostVo>()
                .selectAll(Content.class)
                .selectAs(CollectNum::getCollectNum, "collectNum")
                .selectAs(LikeNum::getLikeNum, "thumbNum")
                .select(User::getAvatarUrl, User::getGender, User::getNickName, User::getGender)
                .selectAs(PiazzaType::getPiazzaName, "typeName")
                .innerJoin(User.class, User::getId, Content::getUserId)
                //获取帖子的收藏数量
                .leftJoin(CollectNum.class, left -> {
                    left.eq(CollectNum::getContentId, Content::getId).eq(CollectNum::getType, ContentTypeEnum.POST.getCode());
                    return left;
                })
                //获取帖子的点赞数量
                .leftJoin(LikeNum.class, left -> {
                    left.eq(LikeNum::getContentId, Content::getId).eq(LikeNum::getType, ContentTypeEnum.POST.getCode());
                    return left;
                })
                .leftJoin(PiazzaType.class, PiazzaType::getId, Content::getTypeId);
        if (type!=null&&type!=0){
            wrapper.eq(Content::getTypeId,type);
        }

        IPage<PostVo> contentIPage = this.selectJoinListPage(new Page<>(pageRequest.getPage(), pageRequest.getRows()), PostVo.class, wrapper);
        for (PostVo record : contentIPage.getRecords()) {
            Likes likeResult = likeService.getOne(new LambdaQueryWrapper<Likes>().eq(Likes::getContentId, record.getId())
                    .eq(Likes::getType, ContentTypeEnum.POST.getCode())
                    .eq(Likes::getUserId, userId));
            Collect collectResult = collectService.getOne(new LambdaQueryWrapper<Collect>().eq(Collect::getContentId, record.getId())
                    .eq(Collect::getCollectType, ContentTypeEnum.POST.getCode())
                    .eq(Collect::getUserId, userId));
            //是否存在点赞记录
            if (likeResult == null) {
                record.setHaveThumb(false);
            } else {
                //已点赞
                if (likeResult.getLikeStatus() == LikeStatusEnum.IS_LIKE.getCode()) {
                    record.setHaveThumb(true);
                } else {
                    record.setHaveThumb(false);
                }
            }
            //是否存在收藏记录
            if (collectResult == null) {
                record.setHaveCollect(false);
            } else {
                //已收藏
                if (collectResult.getCollectStatus() == CollectStatusEnum.IS_COLLECT.getCode()) {
                    record.setHaveCollect(true);
                } else {
                    record.setHaveCollect(false);
                }
            }
        }
        return contentIPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addPost(TokenUserRequest tokenUserRequest, PostAddRequest postAddRequest) {
        Long userId = tokenUserRequest.getId();
        Content post = new Content();
        BeanUtils.copyProperties(postAddRequest, post);
        //前端没传默认图片则使用图片list的第一张
        if (StringUtils.isBlank(postAddRequest.getDefaultImg()) && postAddRequest.getContentImagesList().size() != 0) {
            post.setDefaultImg(postAddRequest.getContentImagesList().get(0));
        }
        post.setUserId(userId);
        boolean save = this.save(post);

        if (save) {
            //开启线程池保存帖子图片
            Future<Boolean> contentImagesSubmit = ThreadPoolUtils.submit(() -> {
                List<String> contentImagesList = postAddRequest.getContentImagesList();
                if (contentImagesList.size() != 0) {
                    for (String image : contentImagesList) {
                        ContentImages contentImage = new ContentImages();
                        contentImage.setContentId(post.getId());
                        contentImage.setImgUrl(image);
                        boolean imageSave = contentImagesService.save(contentImage);
                        if (!imageSave) {
                            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "出错啦");
                        }
                    }

                }
                return true;
            });
            //开启线程池保存点赞收藏信息
            Future<Boolean> collectLikeSubmit = ThreadPoolUtils.submit(() -> {
                Boolean result = likeService.saveThumbCollect(post.getId(), ContentTypeEnum.POST.getCode());
                return result;
            });
            try {
                if (collectLikeSubmit.get() && contentImagesSubmit.get()) {
                    return true;
                }
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }

        } else {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加失败");
        }

        return false;
    }

    @Override
    public Boolean deletePost(TokenUserRequest tokenUserRequest, PostDeleteRequest postDeleteRequest) {
        Long userId = tokenUserRequest.getId();
        Long postId = postDeleteRequest.getPostId();
        Content post = this.getById(postId);
        if (!Objects.equals(post.getUserId(), userId)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "乱jb来是吧");
        }

        boolean result = this.removeById(postId);
        if (result) {
            //开启线程池删除其余信息
            ThreadPoolUtils.execute(() -> {
                //删除图片
                contentImagesService.remove(new LambdaQueryWrapper<ContentImages>().eq(ContentImages::getContentId, postId));
                //删除点赞数量
                likeNumService.remove(new LambdaQueryWrapper<LikeNum>().eq(LikeNum::getContentId, postId)
                        .eq(LikeNum::getType, ContentTypeEnum.POST.getCode()));
                //删除点赞详细信息
                likeService.remove(new LambdaQueryWrapper<Likes>().eq(Likes::getContentId, postId)
                        .eq(Likes::getType, ContentTypeEnum.POST.getCode()));
                //删除收藏数量
                collectNumService.remove(new LambdaQueryWrapper<CollectNum>().eq(CollectNum::getContentId, postId)
                        .eq(CollectNum::getType, ContentTypeEnum.POST.getCode()));
                //删除收藏详细信息
                collectService.remove(new LambdaQueryWrapper<Collect>().eq(Collect::getContentId, postId)
                        .eq(Collect::getCollectType, ContentTypeEnum.POST.getCode()));
            });
        } else {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "系统冒烟了别来沾边");
        }
        return true;
    }

    @Override
    public PostDetailVo getPostDetail(TokenUserRequest tokenUserRequest, Long postId) {
        Long userId = tokenUserRequest.getId();
        MPJLambdaWrapper<PostDetailVo> wrapper = new MPJLambdaWrapper<PostDetailVo>()
                .selectAll(Content.class)
                .selectAs(CollectNum::getCollectNum, "collectNum")
                .selectAs(LikeNum::getLikeNum, "thumbNum")
                .select(User::getAvatarUrl, User::getGender, User::getNickName, User::getGender)
                .selectAs(PiazzaType::getPiazzaName, "typeName")
                .innerJoin(User.class, User::getId, Content::getUserId)
                //获取帖子的收藏数量
                .leftJoin(CollectNum.class, left -> {
                    left.eq(CollectNum::getContentId, Content::getId).eq(CollectNum::getType, ContentTypeEnum.POST.getCode());
                    return left;
                })
                //获取帖子的点赞数量
                .leftJoin(LikeNum.class, left -> {
                    left.eq(LikeNum::getContentId, Content::getId).eq(LikeNum::getType, ContentTypeEnum.POST.getCode());
                    return left;
                })
                .leftJoin(PiazzaType.class, PiazzaType::getId, Content::getTypeId)
                .eq(Content::getId, postId);
        PostDetailVo content = this.selectJoinOne(PostDetailVo.class, wrapper);
        Likes likeResult = likeService.getOne(new LambdaQueryWrapper<Likes>().eq(Likes::getContentId, content.getId())
                .eq(Likes::getType, ContentTypeEnum.POST.getCode())
                .eq(Likes::getUserId, userId));
        Collect collectResult = collectService.getOne(new LambdaQueryWrapper<Collect>().eq(Collect::getContentId, content.getId())
                .eq(Collect::getCollectType, ContentTypeEnum.POST.getCode())
                .eq(Collect::getUserId, userId));
        //是否存在点赞记录
        if (likeResult == null) {
            content.setHaveThumb(false);
        } else {
            //已点赞
            if (likeResult.getLikeStatus() == LikeStatusEnum.IS_LIKE.getCode()) {
                content.setHaveThumb(true);
            } else {
                content.setHaveThumb(false);
            }
        }
        //是否存在收藏记录
        if (collectResult == null) {
            content.setHaveCollect(false);
        } else {
            //已收藏
            if (collectResult.getCollectStatus() == CollectStatusEnum.IS_COLLECT.getCode()) {
                content.setHaveCollect(true);
            } else {
                content.setHaveCollect(false);
            }
        }
        List<ContentImages> list = contentImagesService.list(new LambdaQueryWrapper<ContentImages>().eq(ContentImages::getContentId, content.getId()));
        if (list.size()!=0){
            content.setImgList(list.stream().map(ContentImages::getImgUrl).collect(Collectors.toList()));
        }

        return content;
    }

}




